<!doctype html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.

Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
  <title>goog.labs.gestures recognizers</title>
  <script src="../../base.js"></script>
  <script>
    goog.require('goog.debug.DivConsole');
    goog.require('goog.debug.Logger');
    goog.require('goog.dom');
    goog.require('goog.dom.classes');
    goog.require('goog.events');
    goog.require('goog.events.EventType');
    goog.require('goog.labs.gestures');
  </script>
  <link rel="stylesheet" href="../css/demo.css">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <style>
    body {
      -webkit-user-select: none;
    }
    .container {
      position: relative;
      width: 200px;
      height: 220px;
    }
    .box {
      position: absolute;
      width: 200px;
      height: 200px;
      z-index: 1;

      border: 3px solid #AAAAAA;
      background-color: #666666;
    }
    .box-tapped {
      background-color: #663333;
    }
    .box-swiped {
      background-color: #336666;
    }
    .box-panning {
      background-color: #336633;
    }
    .box-pinching {
      background-color: #333366;
    }
    .box-rotating {
      background-color: #666633;
    }
  </style>
</head>
<body>
  <h1>goog.labs.gestures</h1>
  <div>
    Move/pinch/rotate the boxes. Only supported on touch devices.
  </div>
  <fieldset class="goog-debug-panel">
    <legend>Event log</legend>
    <div class="log" id="log"></div>
  </fieldset>

  tap:
  <div class="container">
    <div id="tapBox" class="box"></div>
  </div>

  swipe:
  <div class="container">
    <div id="swipeBox" class="box"></div>
  </div>

  tap/swipe:
  <div class="container">
    <div id="tapSwipeBox" class="box"></div>
  </div>

  pan:
  <div class="container">
    <div id="panBox" class="box"></div>
  </div>

  pinch:
  <div class="container">
    <div id="pinchBox" class="box"></div>
  </div>

  rotation:
  <div class="container">
    <div id="rotateBox" class="box"></div>
  </div>

  tap/pan/pinch/rotate:
  <div class="container">
    <div id="multiBox" class="box"></div>
  </div>

  <script>
    var logger = goog.debug.Logger.getLogger('gestures');
    new goog.debug.DivConsole(goog.dom.getElement('log')).setCapturing(true);

    // Prevent scrolling and things like the ChromeOS gestures.
    // This is disabled so the page can scroll. A better demo would disable it
    // to prevent weirdness.
    // goog.events.listen(document.body, goog.events.EventType.TOUCHSTART,
    //     function(e) {
    //       e.preventDefault();
    //     });
    // goog.events.listen(document.body, goog.events.EventType.TOUCHMOVE,
    //     function(e) {
    //       e.preventDefault();
    //     });

    // Make all boxes unselectable.
    var allBoxes = document.querySelectorAll('.box');
    for (var n = 0; n < allBoxes.length; n++) {
      goog.style.setUnselectable(allBoxes[n], true);
    }

    function updateTransform(box, tx, ty, scale, angle) {
      // This copied from goog.style.getCssTranslation. It'd be nice to have
      // this in goog.style and much more robust.
      var transformName;
      if (goog.userAgent.IE) {
        transformName = '-ms-transform';
      } else if (goog.userAgent.WEBKIT) {
        transformName = '-webkit-transform';
      } else if (goog.userAgent.OPERA) {
        transformName = '-o-transform';
      } else if (goog.userAgent.GECKO) {
        transformName = '-moz-transform';
      } else {
        transformName = 'transform';
      }
      goog.style.setStyle(box, transformName,
          'translateZ(0) translate(' + tx + 'px,' + ty + 'px) ' +
          'scale(' + scale + ') rotate(' + angle + 'rad)');
    };

    (function() {
      var tapBox = document.getElementById('tapBox');
      var tapGesture = goog.labs.gestures.attachTapGesture(tapBox,
          function(gesture) {
            if (gesture.getState() == goog.labs.gestures.State.RECOGNIZED) {
              goog.dom.classes.add(tapBox, 'box-tapped');
              logger.info('tapped box at ' +
                  gesture.getOffsetX() + ',' + gesture.getOffsetY());
              window.setTimeout(function() {
                goog.dom.classes.remove(tapBox, 'box-tapped');
              }, 200);
            }
          });
      // tapGesture.setTapCount(1);
      // tapGesture.setTouchCount(1);
    })();

    (function() {
      var swipeBox = document.getElementById('swipeBox');
      var swipeGesture = goog.labs.gestures.attachSwipeGesture(swipeBox,
          function(gesture) {
            if (gesture.getState() == goog.labs.gestures.State.RECOGNIZED) {
              goog.dom.classes.add(swipeBox, 'box-swiped');
              logger.info('swiped box: ' + gesture.getDirection());
              window.setTimeout(function() {
                goog.dom.classes.remove(swipeBox, 'box-swiped');
              }, 200);
            }
          });
      // swipeGesture.setTouchCount(1);
    })();

    (function() {
      var tapSwipeBox = document.getElementById('tapSwipeBox');
      var tapGesture = goog.labs.gestures.attachTapGesture(tapSwipeBox,
          function(gesture) {
            if (gesture.getState() == goog.labs.gestures.State.RECOGNIZED) {
              goog.dom.classes.add(tapSwipeBox, 'box-tapped');
              logger.info('tapped box at ' +
                  gesture.getOffsetX() + ',' + gesture.getOffsetY());
              window.setTimeout(function() {
                goog.dom.classes.remove(tapSwipeBox, 'box-tapped');
              }, 200);
            }
          });
      // tapGesture.setTapCount(1);
      // tapGesture.setTouchCount(1);
      var swipeGesture = goog.labs.gestures.attachSwipeGesture(tapSwipeBox,
          function(gesture) {
            if (gesture.getState() == goog.labs.gestures.State.RECOGNIZED) {
              goog.dom.classes.add(tapSwipeBox, 'box-swiped');
              logger.info('swiped box: ' + gesture.getDirection());
              window.setTimeout(function() {
                goog.dom.classes.remove(tapSwipeBox, 'box-swiped');
              }, 200);
            }
          });
      // swipeGesture.setTouchCount(1);
    })();

    (function() {
      var panBox = document.getElementById('panBox');
      var stx = 0;
      var sty = 0;
      var tx = 0;
      var ty = 0;
      var panGesture = goog.labs.gestures.attachPanGesture(panBox,
          function(gesture) {
            switch (gesture.getState()) {
              case goog.labs.gestures.State.BEGAN:
                stx = tx;
                sty = ty;
                goog.dom.classes.add(panBox, 'box-panning');
                logger.info('began translating box');
                break;
              case goog.labs.gestures.State.CHANGED:
                tx = stx + gesture.getTranslationX();
                ty = sty + gesture.getTranslationY();
                updateTransform(panBox, tx, ty, 1, 0);
                logger.info('translating: ' + tx + ',' + ty);
                break;
              case goog.labs.gestures.State.ENDED:
                logger.info('ended translating box');
                goog.dom.classes.remove(panBox, 'box-panning');
                break;
            }
          });
      // panGesture.setMinimumTouchCount(1);
      // panGesture.setMaximumTouchCount(2);
    })();

    (function() {
      var pinchBox = document.getElementById('pinchBox');
      var scale = 1;
      var pinchGesture = goog.labs.gestures.attachPinchGesture(pinchBox,
          function(gesture) {
            switch (gesture.getState()) {
              case goog.labs.gestures.State.BEGAN:
                goog.dom.classes.add(pinchBox, 'box-pinching');
                logger.info('began scaling box');
                break;
              case goog.labs.gestures.State.CHANGED:
                scale *= gesture.getScalingDelta();
                updateTransform(pinchBox, 0, 0, scale, 0);
                logger.info('scaling: ' + scale);
                break;
              case goog.labs.gestures.State.ENDED:
                logger.info('ended scaling box');
                goog.dom.classes.remove(pinchBox, 'box-pinching');
                break;
            }
          });
      // pinchGesture.setMinimumTouchCount(3);
      // pinchGesture.setMaximumTouchCount(2);
    })();

    (function() {
      var rotateBox = document.getElementById('rotateBox');
      var angle = 0;
      var rotateGesture = goog.labs.gestures.attachRotateGesture(rotateBox,
          function(gesture) {
            switch (gesture.getState()) {
              case goog.labs.gestures.State.BEGAN:
                goog.dom.classes.add(rotateBox, 'box-rotating');
                logger.info('began rotating box');
                break;
              case goog.labs.gestures.State.CHANGED:
                angle += gesture.getRotationDelta();
                updateTransform(rotateBox, 0, 0, 1, angle);
                logger.info('rotating: ' + angle);
                break;
              case goog.labs.gestures.State.ENDED:
                logger.info('ended rotating box');
                goog.dom.classes.remove(rotateBox, 'box-rotating');
                break;
            }
          });
    })();

    (function() {
      var multiBox = document.getElementById('multiBox');
      var stx = 0;
      var sty = 0;
      var tx = 0;
      var ty = 0;
      var scale = 1;
      var angle = 0;
      var tapGesture = goog.labs.gestures.attachTapGesture(multiBox,
          function(gesture) {
            if (gesture.getState() == goog.labs.gestures.State.RECOGNIZED) {
              goog.dom.classes.add(multiBox, 'box-tapped');
              logger.info('tapped box at ' +
                  gesture.getOffsetX() + ',' + gesture.getOffsetY());
              window.setTimeout(function() {
                goog.dom.classes.remove(multiBox, 'box-tapped');
              }, 200);
            }
          });
      var panGesture = goog.labs.gestures.attachPanGesture(multiBox,
          function(gesture) {
            switch (gesture.getState()) {
              case goog.labs.gestures.State.BEGAN:
                stx = tx;
                sty = ty;
                goog.dom.classes.add(multiBox, 'box-panning');
                logger.info('began translating box');
                break;
              case goog.labs.gestures.State.CHANGED:
                tx = stx + gesture.getTranslationX();
                ty = sty + gesture.getTranslationY();
                updateTransform(multiBox, tx, ty, scale, angle);
                logger.info('translating: ' + tx + ',' + ty);
                break;
              case goog.labs.gestures.State.ENDED:
                logger.info('ended translating box');
                goog.dom.classes.remove(multiBox, 'box-panning');
                break;
            }
          });
      var pinchGesture = goog.labs.gestures.attachPinchGesture(multiBox,
          function(gesture) {
            switch (gesture.getState()) {
              case goog.labs.gestures.State.BEGAN:
                goog.dom.classes.add(multiBox, 'box-pinching');
                logger.info('began scaling box');
                break;
              case goog.labs.gestures.State.CHANGED:
                scale *= gesture.getScalingDelta();
                updateTransform(multiBox, tx, ty, scale, angle);
                logger.info('scaling: ' + scale);
                break;
              case goog.labs.gestures.State.ENDED:
                logger.info('ended scaling box');
                goog.dom.classes.remove(multiBox, 'box-pinching');
                break;
            }
          });
      var rotateGesture = goog.labs.gestures.attachRotateGesture(multiBox,
          function(gesture) {
            switch (gesture.getState()) {
              case goog.labs.gestures.State.BEGAN:
                goog.dom.classes.add(multiBox, 'box-rotating');
                logger.info('began rotating box');
                break;
              case goog.labs.gestures.State.CHANGED:
                angle += gesture.getRotationDelta();
                updateTransform(multiBox, tx, ty, scale, angle);
                logger.info('rotating: ' + angle);
                break;
              case goog.labs.gestures.State.ENDED:
                logger.info('ended rotating box');
                goog.dom.classes.remove(multiBox, 'box-rotating');
                break;
            }
          });

      // Allow all gestures to recognize together.
      goog.labs.gestures.allowSimultaneousRecognition(
          panGesture, pinchGesture, rotateGesture);
    })();
  </script>
</body>
</html>
